
#include "GUI/Misc/Fadescreen.h"

namespace TD_GUI {


	/************************************************************************/
	/* Private functionalities                                              */
	/************************************************************************/
	void Fadescreen::initFadescreen() {
		SDL_Surface *rawSurface;
		Uint32 rmask, gmask, bmask, amask;

		/* SDL interprets each pixel as a 32-bit number, so our masks must depend
		on the endianness (byte order) of the machine */

#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
		rmask = 0xff000000;
		gmask = 0x00ff0000;
		bmask = 0x0000ff00;
		amask = 0x000000ff;
#else
		rmask = 0x000000ff;
		gmask = 0x0000ff00;
		bmask = 0x00ff0000;
		amask = 0xff000000;
#endif

		rawSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, TD_Game::screenWidth, TD_Game::screenHeight, 8,
			rmask, gmask, bmask, amask);

		if (rawSurface == NULL) {
#ifndef _WII
			string exceptionStr("CreateRGBSurface failed: %s\n");
			exceptionStr += SDL_GetError();
			throw(bad_exception(exceptionStr.c_str()));
			exit(1);
#endif
			
		}


		m_pFadingScreen = SDL_DisplayFormat(rawSurface);
		SDL_FreeSurface(rawSurface); //Destructiing the rawsurface, since it is no use anymore

		SDL_FillRect(m_pFadingScreen, NULL, SDL_MapRGB(m_pFadingScreen->format, 0x00000000,
			0x00000000, 0x00000000));

		SDL_SetAlpha(m_pFadingScreen, SDL_SRCALPHA | SDL_RLEACCEL, 255);
	}

	void Fadescreen::update(unsigned int deltaTime) {
		if(m_isFadingIn) {
			if(!m_isFinished) {
				m_displacement -= m_fadeVelocity*deltaTime;
				if(m_displacement <= -1) {
					int intDisplacement = (int) m_displacement;
					m_displacement -= intDisplacement;
					m_alphaChannel += intDisplacement;

					SDL_SetAlpha(m_pFadingScreen, SDL_SRCALPHA | SDL_RLEACCEL, m_alphaChannel); 

					if(m_alphaChannel <= 0 || m_alphaChannel - intDisplacement <= 0) {
						m_alphaChannel = 0;
						m_isFinished = true;
						SDL_SetAlpha(m_pFadingScreen, SDL_SRCALPHA | SDL_RLEACCEL, m_alphaChannel); 
					}
				}
			}

		} else if(m_isFadingOut) {

			if(!m_isFinished) {
				m_displacement += m_fadeVelocity*deltaTime;
				if(m_displacement >= 1){
					int intDisplacement = (int) m_displacement;
					m_displacement -= intDisplacement;
					m_alphaChannel += intDisplacement;

					SDL_SetAlpha(m_pFadingScreen, SDL_SRCALPHA | SDL_RLEACCEL, m_alphaChannel); 

					if(m_alphaChannel >= 255 || m_alphaChannel + intDisplacement >= 255) {
						m_alphaChannel = 255;
						m_isFinished = true;
					} 
				}
			}
		}
	}

	/************************************************************************/
	/* ctors and dtors                                                      */
	/************************************************************************/
	Fadescreen::Fadescreen()
	{
		m_offset.x = m_offset.y = 0;
		m_displacement = 0;
		initFadescreen();
	}

	Fadescreen::Fadescreen(const Fadescreen &rhs) {


	}
	Fadescreen::~Fadescreen() {
		SDL_FreeSurface(m_pFadingScreen);
	}

	/************************************************************************/
	/* Functionalities                                                      */
	/************************************************************************/

	void Fadescreen::render(SDL_Surface *g_pSurface, unsigned int deltaTime) {
		update(deltaTime);
		SDL_BlitSurface(m_pFadingScreen, NULL, g_pSurface, &m_offset); 
	}
	void Fadescreen::startFadeIn(float fadeVelocity) {
		m_fadeVelocity = fadeVelocity;
		m_isFadingIn = true;
		m_isFadingOut = false;
		m_isFinished = false;
		m_alphaChannel = 255;
	}

	void Fadescreen::startFadeOut(float fadeVelocity) {
		m_fadeVelocity = fadeVelocity;
		m_isFadingIn = false;
		m_isFadingOut = true;
		m_isFinished = false;
		m_alphaChannel = 0;
	}


}